﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;

namespace ShopeeSdk
{
    public class DefaultShopeeClient : IShopeeClient
    {
        private readonly string baseUrl = "https://partner.shopeemobile.com/api/v1/";
        private readonly int partnerId;
        private readonly string key;
        private readonly int shopId;

        public DefaultShopeeClient(int partnerId,int shopId ,string key, string baseUrl=null)
        {
            this.partnerId = partnerId;
            this.shopId = shopId;
            this.key = key;

            if (!string.IsNullOrEmpty(baseUrl))
                this.baseUrl = baseUrl;
        }

        public T Excute<T>(ShopeeRequest<T> request) where T : ShopeeResponse
        {
            string requestUrl = baseUrl+request.RequestUrlEndPath;

            request.PartnerId = partnerId;
            request.ShopId = shopId;

            string content = JsonConvert.SerializeObject(request);

            string baseString = $"{requestUrl}|{content}";

            string auth = HMACSHA256Encrypt(key, baseString);

            string jsonResult = DoPost(requestUrl, content, auth);

            return JsonConvert.DeserializeObject<T>(jsonResult);
        }

        string DoPost(string url, string content, string authorization)
        {
            string result = string.Empty;
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "POST";
            req.ContentType = "application/json";
            req.Headers.Add("Authorization", authorization);

            #region 添加Post 参数
            byte[] data = Encoding.UTF8.GetBytes(content);
            req.ContentLength = data.Length;
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
            }
            #endregion
            HttpWebResponse resp;
            try
            {
                resp = (HttpWebResponse)req.GetResponse();
                Stream stream = resp.GetResponseStream();

                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                {
                    result = reader.ReadToEnd();
                }
            }
            catch (WebException ex)
            {
                Stream stream = ex.Response.GetResponseStream();
                
                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                {
                    result = reader.ReadToEnd();
                }
            }
            return result;

        }

        string HMACSHA256Encrypt(string password, string encrtyString)
        {
            byte[] bytValue = Encoding.UTF8.GetBytes(encrtyString);
            HMACSHA256 sha256 = new HMACSHA256(Encoding.UTF8.GetBytes(password));
            byte[] retVal = sha256.ComputeHash(bytValue);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }
            return sb.ToString();
        }
    }
}
